bitkeeper revision 1.536 (3f9fd20aglcfc5h0kB1oldciJuy2dQ)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Wed, 29 Oct 2003 14:43:22 +0000 (14:43 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Wed, 29 Oct 2003 14:43:22 +0000 (14:43 +0000)
Many files:
  Modified blkdev and network interfaces to allow expedited flushing of pending request buffers.

19 files changed:
extras/mini-os/h/hypervisor.h
extras/mini-os/head.S
tools/internal/xi_build.c
xen/arch/i386/entry.S
xen/common/domain.c
xen/common/network.c
xen/drivers/block/xen_block.c
xen/include/hypervisor-ifs/block.h
xen/include/hypervisor-ifs/dom0_ops.h
xen/include/hypervisor-ifs/hypervisor-if.h
xen/include/hypervisor-ifs/network.h
xen/net/dev.c
xenolinux-2.4.22-sparse/arch/xeno/drivers/block/xl_block.c
xenolinux-2.4.22-sparse/arch/xeno/drivers/network/network.c
xenolinux-2.4.22-sparse/arch/xeno/kernel/head.S
xenolinux-2.4.22-sparse/arch/xeno/kernel/setup.c
xenolinux-2.4.22-sparse/arch/xeno/mm/init.c
xenolinux-2.4.22-sparse/include/asm-xeno/fixmap.h
xenolinux-2.4.22-sparse/include/asm-xeno/hypervisor.h

index 3519b6faff71b046a55fdb7adbd3cf42ccfd1641..23c39134f38ea8fce7dc0627d547c44143ea6076 100644 (file)
@@ -103,12 +103,13 @@ static inline int HYPERVISOR_set_callbacks(
     return ret;
 }
 
-static inline int HYPERVISOR_net_update(void)
+static inline int HYPERVISOR_net_io_op(unsigned int op, unsigned int idx)
 {
     int ret;
     __asm__ __volatile__ (
         TRAP_INSTR
-        : "=a" (ret) : "0" (__HYPERVISOR_net_update) );
+        : "=a" (ret) : "0" (__HYPERVISOR_net_io_op),
+        "b" (op), "c" (idx) );
 
     return ret;
 }
@@ -165,12 +166,13 @@ static inline int HYPERVISOR_network_op(void *network_op)
     return ret;
 }
 
-static inline int HYPERVISOR_block_io_op(void)
+static inline int HYPERVISOR_block_io_op(unsigned int op)
 {
     int ret;
     __asm__ __volatile__ (
         TRAP_INSTR
-        : "=a" (ret) : "0" (__HYPERVISOR_block_io_op) ); 
+        : "=a" (ret) : "0" (__HYPERVISOR_block_io_op),
+        "b" (op) ); 
 
     return ret;
 }
index 3f4e6670c373ffbd6a737718a48a65fa6b46d91e..d5cb19f574c36efad5aa29b3d64badda1f42ee79 100644 (file)
@@ -1,9 +1,8 @@
 #include <os.h>
 
 /* Offsets in start_info structure */
-#define SHARED_INFO  4
-#define MOD_START   12
-#define MOD_LEN     16
+#define MOD_START    4
+#define MOD_LEN      8
 
 #define ENTRY(X) .globl X ; X :
 
@@ -31,10 +30,10 @@ _start:
 
         /* Clear BSS first so that there are no surprises... */
 2:      xorl %eax,%eax
-           movl $__bss_start,%edi
-           movl $_end,%ecx
-           subl %edi,%ecx
-           rep stosb
+        movl $__bss_start,%edi
+        movl $_end,%ecx
+        subl %edi,%ecx
+        rep stosb
 
         push %esi 
         call start_kernel
index 24863744fbafa6317d2baf5f95fa456f5768d9c7..429048ec94ed662d52fee56c4c8b2f5e15cced26 100644 (file)
@@ -230,12 +230,8 @@ static int setup_guestos(
 
     alloc_index = tot_pages - 1;
 
-    /*
-     * Count bottom-level PTs, rounding up. Include one PTE for shared info. We
-     * therefore add 1024 because 1 is for shared_info, 1023 is to round up.
-     */
-    num_pt_pages = 
-        (l1_table_offset(virt_load_addr) + tot_pages + 1024) / 1024;
+    /* Count bottom-level PTs, rounding up. */
+    num_pt_pages = (l1_table_offset(virt_load_addr) + tot_pages + 1023) / 1024;
 
     /* We must also count the page directory. */
     num_pt_pages++;
@@ -250,7 +246,6 @@ static int setup_guestos(
     l2tab = page_array[alloc_index] << PAGE_SHIFT;
     alloc_index--;
     meminfo->l2_pgt_addr = l2tab;
-    meminfo->virt_shinfo_addr = virt_load_addr + (tot_pages << PAGE_SHIFT);
 
     /*
      * Pin down l2tab addr as page dir page - causes hypervisor to provide
@@ -261,16 +256,12 @@ static int setup_guestos(
     pgt_updates++;
     num_pgt_updates++;
 
-    /*
-     * Initialise the page tables. The final iteration is for the shared_info
-     * PTE -- we break out before filling in the entry, as that is done by
-     * Xen during final setup.
-     */
+    /* Initialise the page tables. */
     if ( (vl2tab = map_pfn(l2tab >> PAGE_SHIFT)) == NULL )
         goto error_out;
     memset(vl2tab, 0, PAGE_SIZE);
     vl2e = vl2tab + l2_table_offset(virt_load_addr);
-    for ( count = 0; count < (tot_pages + 1); count++ )
+    for ( count = 0; count < tot_pages; count++ )
     {    
         if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 ) 
         {
@@ -291,9 +282,6 @@ static int setup_guestos(
             vl2e++;
         }
 
-        /* The last PTE we consider is filled in later by Xen. */
-        if ( count == tot_pages ) break;
-               
         if ( count < pt_start )
         {
             pgt_updates->ptr = (unsigned long)vl1e;
index 2ce1c30784cf01c6afce38e734d8019ff2b38a57..77ad757d6235054874a7d5479a96b65cc7541a66 100644 (file)
@@ -710,7 +710,7 @@ ENTRY(hypervisor_call_table)
         .long SYMBOL_NAME(do_set_gdt)
         .long SYMBOL_NAME(do_stack_switch)
         .long SYMBOL_NAME(do_set_callbacks)
-        .long SYMBOL_NAME(do_net_update)
+        .long SYMBOL_NAME(do_net_io_op)
         .long SYMBOL_NAME(do_fpu_taskswitch)
         .long SYMBOL_NAME(do_yield)
         .long SYMBOL_NAME(kill_domain)
index f16a25f30c567946b57a85e3036ff0e756ae2b90..b817e0f36f9c9a6b4f24c0d9304f752e645c6f6b 100644 (file)
@@ -347,7 +347,6 @@ void release_task(struct task_struct *p)
 int final_setup_guestos(struct task_struct * p, dom_meminfo_t * meminfo)
 {
     l2_pgentry_t * l2tab;
-    l1_pgentry_t * l1tab;
     start_info_t * virt_startinfo_addr;
     unsigned long virt_stack_addr;
     unsigned long phys_l2tab;
@@ -374,19 +373,9 @@ int final_setup_guestos(struct task_struct * p, dom_meminfo_t * meminfo)
     p->mm.pagetable = mk_pagetable(phys_l2tab);
     unmap_domain_mem(l2tab);
 
-    /* map in the shared info structure */
-    phys_l2tab = pagetable_val(p->mm.pagetable); 
-    l2tab = map_domain_mem(phys_l2tab);
-    l2tab += l2_table_offset(meminfo->virt_shinfo_addr);
-    l1tab = map_domain_mem(l2_pgentry_to_phys(*l2tab));
-    l1tab += l1_table_offset(meminfo->virt_shinfo_addr);
-    *l1tab = mk_l1_pgentry(__pa(p->shared_info) | L1_PROT);
-    unmap_domain_mem((void *)((unsigned long)l2tab & PAGE_MASK));
-    unmap_domain_mem((void *)((unsigned long)l1tab & PAGE_MASK));
-
     /* set up the shared info structure */
     update_dom_time(p->shared_info);
-    p->shared_info->domain_time  = 0;
+    p->shared_info->domain_time = 0;
 
     /* we pass start info struct to guest os as function parameter on stack */
     virt_startinfo_addr = (start_info_t *)meminfo->virt_startinfo_addr;
@@ -401,7 +390,7 @@ int final_setup_guestos(struct task_struct * p, dom_meminfo_t * meminfo)
 
     memset(virt_startinfo_addr, 0, sizeof(*virt_startinfo_addr));
     virt_startinfo_addr->nr_pages = p->tot_pages;
-    virt_startinfo_addr->shared_info = (shared_info_t *)meminfo->virt_shinfo_addr;
+    virt_startinfo_addr->shared_info = virt_to_phys(p->shared_info);
     virt_startinfo_addr->pt_base = meminfo->virt_load_addr + 
                     ((p->tot_pages - 1) << PAGE_SHIFT);
    
@@ -474,7 +463,7 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params,
     int i, dom = p->domain;
     unsigned long phys_l1tab, phys_l2tab;
     unsigned long cur_address, alloc_address;
-    unsigned long virt_load_address, virt_stack_address, virt_shinfo_address;
+    unsigned long virt_load_address, virt_stack_address;
     start_info_t  *virt_startinfo_address;
     unsigned long count;
     unsigned long alloc_index;
@@ -551,16 +540,11 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params,
     memset(l2tab, 0, DOMAIN_ENTRIES_PER_L2_PAGETABLE*sizeof(l2_pgentry_t));
     p->mm.pagetable = mk_pagetable(phys_l2tab);
 
-    /*
-     * NB. The upper limit on this loop does one extra page. This is to make 
-     * sure a pte exists when we want to map the shared_info struct.
-     */
-
     l2tab += l2_table_offset(virt_load_address);
     cur_address = list_entry(p->pg_head.next, struct pfn_info, list) -
         frame_table;
     cur_address <<= PAGE_SHIFT;
-    for ( count = 0; count < p->tot_pages + 1; count++ )
+    for ( count = 0; count < p->tot_pages; count++ )
     {
         if ( !((unsigned long)l1tab & (PAGE_SIZE-1)) )
         {
@@ -574,14 +558,11 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params,
         }
         *l1tab++ = mk_l1_pgentry(cur_address|L1_PROT);
         
-        if ( count < p->tot_pages )
-        {
-            page = frame_table + (cur_address >> PAGE_SHIFT);
-            page->flags = dom | PGT_writeable_page | PG_need_flush;
-            page->type_count = page->tot_count = 1;
-            /* Set up the MPT entry. */
-            machine_to_phys_mapping[cur_address >> PAGE_SHIFT] = count;
-        }
+        page = frame_table + (cur_address >> PAGE_SHIFT);
+        page->flags = dom | PGT_writeable_page | PG_need_flush;
+        page->type_count = page->tot_count = 1;
+        /* Set up the MPT entry. */
+        machine_to_phys_mapping[cur_address >> PAGE_SHIFT] = count;
 
         list_ent = frame_table[cur_address >> PAGE_SHIFT].list.next;
         cur_address = list_entry(list_ent, struct pfn_info, list) -
@@ -630,17 +611,9 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params,
     page->flags = dom | PGT_l2_page_table;
     unmap_domain_mem(l1start);
 
-    /* Map in the the shared info structure. */
-    virt_shinfo_address = virt_load_address + (p->tot_pages << PAGE_SHIFT); 
-    l2tab = l2start + l2_table_offset(virt_shinfo_address);
-    l1start = l1tab = map_domain_mem(l2_pgentry_to_phys(*l2tab));
-    l1tab += l1_table_offset(virt_shinfo_address);
-    *l1tab = mk_l1_pgentry(__pa(p->shared_info)|L1_PROT);
-    unmap_domain_mem(l1start);
-
     /* Set up shared info area. */
     update_dom_time(p->shared_info);
-    p->shared_info->domain_time  = 0;
+    p->shared_info->domain_time = 0;
 
     virt_startinfo_address = (start_info_t *)
         (virt_load_address + ((alloc_index - 1) << PAGE_SHIFT));
@@ -671,8 +644,7 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params,
     /* Set up start info area. */
     memset(virt_startinfo_address, 0, sizeof(*virt_startinfo_address));
     virt_startinfo_address->nr_pages = p->tot_pages;
-    virt_startinfo_address->shared_info = 
-        (shared_info_t *)virt_shinfo_address;
+    virt_startinfo_address->shared_info = virt_to_phys(p->shared_info);
     virt_startinfo_address->pt_base = virt_load_address + 
         ((p->tot_pages - 1) << PAGE_SHIFT); 
 
index d51195059e17aa8d20c65f6dd2fbaaf638c18f20..367790644a1989c2b6565184800ea5be9496b692 100644 (file)
@@ -159,40 +159,10 @@ net_vif_t *create_net_vif(int domain)
 
 void destroy_net_vif(net_vif_t *vif)
 {
-    int i;
-    unsigned long *pte, flags;
-    struct pfn_info *page;
+    extern long flush_bufs_for_vif(net_vif_t *vif);
     struct task_struct *p = vif->domain;
-
-    /* Return any outstanding receive buffers to the guest OS. */
-    spin_lock_irqsave(&p->page_lock, flags);
-    for ( i = vif->rx_cons; i != vif->rx_prod; i = ((i+1) & (RX_RING_SIZE-1)) )
-    {
-        rx_shadow_entry_t *rx = vif->rx_shadow_ring + i;
-
-        /* Release the page-table page. */
-        page = frame_table + (rx->pte_ptr >> PAGE_SHIFT);
-        put_page_type(page);
-        put_page_tot(page);
-
-        /* Give the buffer page back to the domain. */
-        page = frame_table + rx->buf_pfn;
-        list_add(&page->list, &p->pg_head);
-        page->flags = vif->domain->domain;
-
-        /* Patch up the PTE if it hasn't changed under our feet. */
-        pte = map_domain_mem(rx->pte_ptr);
-        if ( !(*pte & _PAGE_PRESENT) )
-        {
-            *pte = (rx->buf_pfn<<PAGE_SHIFT) | (*pte & ~PAGE_MASK) | 
-                _PAGE_RW | _PAGE_PRESENT;
-            page->flags |= PGT_writeable_page | PG_need_flush;
-            page->type_count = page->tot_count = 1;
-        }
-        unmap_domain_mem(pte);
-    }
-    spin_unlock_irqrestore(&p->page_lock, flags);
-
+    (void)flush_bufs_for_vif(vif);
+    UNSHARE_PFN(virt_to_page(vif->shared_rings));
     kmem_cache_free(net_vif_cache, vif);
     put_task_struct(p);
 }
index 3a56144007e075215f8b7a224b415d36ff5143f9..addadcf7dd6098bc648be362c600a8e95b407191 100644 (file)
@@ -241,11 +241,26 @@ static void end_block_io_op(struct buffer_head *bh, int uptodate)
  * GUEST-OS SYSCALL -- Indicates there are requests outstanding.
  */
 
-long do_block_io_op(void)
+long do_block_io_op(unsigned int op)
 {
-    add_to_blkdev_list_tail(current);
-    maybe_trigger_io_schedule();
-    return 0L;
+    long ret = 0;
+
+    switch ( op )
+    {
+    case BLKOP_PUSH_BUFFERS:
+        add_to_blkdev_list_tail(current);
+        maybe_trigger_io_schedule();
+        break;
+
+    case BLKOP_FLUSH_BUFFERS:
+        break;
+
+    default:
+        ret = -EINVAL;
+        break;
+    }
+
+    return ret;
 }
 
 
index 5c9a0caa779397cfd461a48c77bc62d5430d041c..9a5dd753e8695c4c678538d8c63e33804bd7e5f5 100644 (file)
@@ -8,6 +8,14 @@
 #ifndef __BLOCK_H__
 #define __BLOCK_H__
 
+/*
+ * Command values for block_io_op()
+ */
+
+#define BLKOP_PUSH_BUFFERS   0  /* Notify Xen of new requests on the ring. */
+#define BLKOP_FLUSH_BUFFERS  1  /* Flush all pending request buffers.      */
+
+
 /*
  * Device numbers
  */
index 1e7ab9a4891e81205e5f3aef47284fa8b9544222..55544e162696ba2b042348cbd8caafcf3b41675f 100644 (file)
@@ -57,7 +57,6 @@ typedef struct domain_launch
     unsigned int  domain;
     unsigned long l2_pgt_addr;
     unsigned long virt_load_addr;
-    unsigned long virt_shinfo_addr;
     unsigned long virt_startinfo_addr;
     unsigned int num_vifs;
     char cmd_line[MAX_CMD_LEN];
index 3213d0b6c65d47ae2d38b1dbf9498c8543700e3c..33115a7941b44c6010530c3fa1c8b73630670597 100644 (file)
@@ -19,9 +19,9 @@
  * NB. The reserved range is inclusive (that is, both FIRST_RESERVED_GDT_ENTRY
  * and LAST_RESERVED_GDT_ENTRY are reserved).
  */
-#define NR_RESERVED_GDT_ENTRIES         40
-#define FIRST_RESERVED_GDT_ENTRY       256
-#define LAST_RESERVED_GDT_ENTRY         \
+#define NR_RESERVED_GDT_ENTRIES    40
+#define FIRST_RESERVED_GDT_ENTRY   256
+#define LAST_RESERVED_GDT_ENTRY    \
   (FIRST_RESERVED_GDT_ENTRY + NR_RESERVED_GDT_ENTRIES - 1)
 
 /*
  * are also present in the initial GDT, many OSes will be able to avoid
  * installing their own GDT.
  */
-#define FLAT_RING1_CS          0x0819
-#define FLAT_RING1_DS          0x0821
-#define FLAT_RING3_CS          0x082b
-#define FLAT_RING3_DS          0x0833
+#define FLAT_RING1_CS 0x0819
+#define FLAT_RING1_DS 0x0821
+#define FLAT_RING3_CS 0x082b
+#define FLAT_RING3_DS 0x0833
 
 
 /*
  */
 
 /* EAX = vector; EBX, ECX, EDX, ESI, EDI = args 1, 2, 3, 4, 5. */
-#define __HYPERVISOR_set_trap_table       0
-#define __HYPERVISOR_mmu_update                   1
-#define __HYPERVISOR_console_write        2
-#define __HYPERVISOR_set_gdt              3
+#define __HYPERVISOR_set_trap_table        0
+#define __HYPERVISOR_mmu_update            1
+#define __HYPERVISOR_console_write         2
+#define __HYPERVISOR_set_gdt               3
 #define __HYPERVISOR_stack_switch          4
 #define __HYPERVISOR_set_callbacks         5
-#define __HYPERVISOR_net_update                   6
-#define __HYPERVISOR_fpu_taskswitch       7
-#define __HYPERVISOR_yield                8
-#define __HYPERVISOR_exit                 9
-#define __HYPERVISOR_dom0_op             10
-#define __HYPERVISOR_network_op                  11
-#define __HYPERVISOR_block_io_op         12
-#define __HYPERVISOR_set_debugreg        13
-#define __HYPERVISOR_get_debugreg        14
-#define __HYPERVISOR_update_descriptor   15
-#define __HYPERVISOR_set_fast_trap       16
-#define __HYPERVISOR_dom_mem_op                  17
-#define __HYPERVISOR_multicall           18
+#define __HYPERVISOR_net_io_op             6
+#define __HYPERVISOR_fpu_taskswitch        7
+#define __HYPERVISOR_yield                 8
+#define __HYPERVISOR_exit                  9
+#define __HYPERVISOR_dom0_op              10
+#define __HYPERVISOR_network_op           11
+#define __HYPERVISOR_block_io_op          12
+#define __HYPERVISOR_set_debugreg         13
+#define __HYPERVISOR_get_debugreg         14
+#define __HYPERVISOR_update_descriptor    15
+#define __HYPERVISOR_set_fast_trap        16
+#define __HYPERVISOR_dom_mem_op           17
+#define __HYPERVISOR_multicall            18
 #define __HYPERVISOR_kbd_op               19
 #define __HYPERVISOR_update_va_mapping    20
 
@@ -276,19 +276,19 @@ typedef struct shared_info_st {
  * NB. We expect that this struct is smaller than a page.
  */
 typedef struct start_info_st {
-    unsigned long nr_pages;      /* total pages allocated to this domain */
-    shared_info_t *shared_info;          /* VIRTUAL address of shared info struct */
-    unsigned long  pt_base;      /* VIRTUAL address of page directory */
-    unsigned long mod_start;     /* VIRTUAL address of pre-loaded module */
-    unsigned long mod_len;       /* size (bytes) of pre-loaded module */
-    /* Machine address of net rings for each VIF. Will be page aligned. */
-    unsigned long net_rings[MAX_DOMAIN_VIFS];
-    unsigned char net_vmac[MAX_DOMAIN_VIFS][6];
-    /* Machine address of block-device ring. Will be page aligned. */
-    unsigned long blk_ring;
-    unsigned int  dom_id;
-    unsigned long flags; 
-    unsigned char cmd_line[1];   /* variable-length */
+    /* THE FOLLOWING ARE ONLY FILLED IN ON INITIAL BOOT (NOT RESUME).      */
+    unsigned long pt_base;       /* VIRTUAL address of page directory.    */
+    unsigned long mod_start;     /* VIRTUAL address of pre-loaded module. */
+    unsigned long mod_len;       /* Size (bytes) of pre-loaded module.    */
+    /* THE FOLLOWING ARE FILLED IN BOTH ON INITIAL BOOT AND ON RESUME.     */
+    unsigned long nr_pages;      /* total pages allocated to this domain. */
+    unsigned long shared_info;   /* MACHINE address of shared info struct.*/
+    unsigned int  dom_id;         /* Domain identifier.                    */
+    unsigned long flags;          /* SIF_xxx flags.                        */
+    unsigned long net_rings[MAX_DOMAIN_VIFS];   /* MACHINE address of ring.*/
+    unsigned char net_vmac[MAX_DOMAIN_VIFS][6]; /* MAC address of VIF.     */
+    unsigned long blk_ring;       /* MACHINE address of blkdev ring.       */
+    unsigned char cmd_line[1];   /* Variable-length options.              */
 } start_info_t;
 
 /* These flags are passed in the 'flags' field of start_info_t. */
index c35f1bab1527f6133caf818ae7459e03bb091094..8681b5253ea22ee821f02cd4f602255aef227fc9 100644 (file)
 #ifndef __RING_H__
 #define __RING_H__
 
+/*
+ * Command values for block_io_op()
+ */
+
+#define NETOP_PUSH_BUFFERS    0  /* Notify Xen of new buffers on the rings. */
+#define NETOP_FLUSH_BUFFERS   1  /* Flush all pending request buffers.      */
+
+
 typedef struct tx_req_entry_st
 {
     unsigned short id;
index 2fcf935319189beb7cb7bb6eb01069352bdbb57e..b2a4212e3e182e4dfd889a87d417d6b7bbaae8e9 100644 (file)
@@ -1877,7 +1877,7 @@ static int get_tx_bufs(net_vif_t *vif)
         tx     = shared_rings->tx_ring[i].req;
         target = VIF_DROP;
 
-        if ( (tx.size < PKT_PROT_LEN) || (tx.size > ETH_FRAME_LEN) )
+        if ( (tx.size <= PKT_PROT_LEN) || (tx.size > ETH_FRAME_LEN) )
         {
             DPRINTK("Bad packet size: %d\n", tx.size);
             __make_tx_response(vif, tx.id, RING_STATUS_BAD_PAGE);
@@ -2019,133 +2019,225 @@ static int get_tx_bufs(net_vif_t *vif)
 }
 
 
-/*
- * do_net_update:
- * 
- * Called from guest OS to notify updates to its transmit and/or receive
- * descriptor rings.
- */
-
-long do_net_update(void)
+static long get_bufs_from_vif(net_vif_t *vif)
 {
     net_ring_t *shared_rings;
-    net_vif_t *vif;
     net_idx_t *shared_idxs;
-    unsigned int i, j, idx;
+    unsigned int i, j;
     rx_req_entry_t rx;
     unsigned long  pte_pfn, buf_pfn;
     struct pfn_info *pte_page, *buf_page;
+    struct task_struct *p = vif->domain;
     unsigned long *ptep;    
 
-    perfc_incr(net_hypercalls);
-
-    for ( idx = 0; idx < MAX_DOMAIN_VIFS; idx++ )
-    {
-        if ( (vif = current->net_vif_list[idx]) == NULL )
-            break;
-
-        shared_idxs  = vif->shared_idxs;
-        shared_rings = vif->shared_rings;
+    shared_idxs  = vif->shared_idxs;
+    shared_rings = vif->shared_rings;
         
-        /*
-         * PHASE 1 -- TRANSMIT RING
-         */
+    /*
+     * PHASE 1 -- TRANSMIT RING
+     */
 
-        if ( get_tx_bufs(vif) )
-        {
-            add_to_net_schedule_list_tail(vif);
-            maybe_schedule_tx_action();
-        }
+    if ( get_tx_bufs(vif) )
+    {
+        add_to_net_schedule_list_tail(vif);
+        maybe_schedule_tx_action();
+    }
 
-        /*
-         * PHASE 2 -- RECEIVE RING
-         */
+    /*
+     * PHASE 2 -- RECEIVE RING
+     */
 
-        /*
-         * Collect up new receive buffers. We collect up to the guest OS's
-         * new producer index, but take care not to catch up with our own
-         * consumer index.
-         */
-        j = vif->rx_prod;
-        for ( i = vif->rx_req_cons; 
-              (i != shared_idxs->rx_req_prod) && 
-                  (((vif->rx_resp_prod-i) & (RX_RING_SIZE-1)) != 1); 
-              i = RX_RING_INC(i) )
-        {
-            rx = shared_rings->rx_ring[i].req;
+    /*
+     * Collect up new receive buffers. We collect up to the guest OS's new
+     * producer index, but take care not to catch up with our own consumer
+     * index.
+     */
+    j = vif->rx_prod;
+    for ( i = vif->rx_req_cons; 
+          (i != shared_idxs->rx_req_prod) && 
+              (((vif->rx_resp_prod-i) & (RX_RING_SIZE-1)) != 1); 
+          i = RX_RING_INC(i) )
+    {
+        rx = shared_rings->rx_ring[i].req;
 
-            pte_pfn = rx.addr >> PAGE_SHIFT;
-            pte_page = frame_table + pte_pfn;
+        pte_pfn = rx.addr >> PAGE_SHIFT;
+        pte_page = frame_table + pte_pfn;
             
-            spin_lock_irq(&current->page_lock);
-            if ( (pte_pfn >= max_page) || 
-                 ((pte_page->flags & (PG_type_mask | PG_domain_mask)) != 
-                  (PGT_l1_page_table | current->domain)) ) 
-            {
-                DPRINTK("Bad page frame for ppte %d,%08lx,%08lx,%08lx\n",
-                        current->domain, pte_pfn, max_page, pte_page->flags);
-                spin_unlock_irq(&current->page_lock);
-                make_rx_response(vif, rx.id, 0, RING_STATUS_BAD_PAGE, 0);
-                continue;
-            }
+        spin_lock_irq(&p->page_lock);
+        if ( (pte_pfn >= max_page) || 
+             ((pte_page->flags & (PG_type_mask | PG_domain_mask)) != 
+              (PGT_l1_page_table | p->domain)) ) 
+        {
+            DPRINTK("Bad page frame for ppte %d,%08lx,%08lx,%08lx\n",
+                    p->domain, pte_pfn, max_page, pte_page->flags);
+            spin_unlock_irq(&p->page_lock);
+            make_rx_response(vif, rx.id, 0, RING_STATUS_BAD_PAGE, 0);
+            continue;
+        }
             
-            ptep = map_domain_mem(rx.addr);
+        ptep = map_domain_mem(rx.addr);
             
-            if ( !(*ptep & _PAGE_PRESENT) )
-            {
-                DPRINTK("Invalid PTE passed down (not present)\n");
-                make_rx_response(vif, rx.id, 0, RING_STATUS_BAD_PAGE, 0);
-                goto rx_unmap_and_continue;
-            }
+        if ( !(*ptep & _PAGE_PRESENT) )
+        {
+            DPRINTK("Invalid PTE passed down (not present)\n");
+            make_rx_response(vif, rx.id, 0, RING_STATUS_BAD_PAGE, 0);
+            goto rx_unmap_and_continue;
+        }
             
-            buf_pfn  = *ptep >> PAGE_SHIFT;
-            buf_page = frame_table + buf_pfn;
+        buf_pfn  = *ptep >> PAGE_SHIFT;
+        buf_page = frame_table + buf_pfn;
 
-            if ( ((buf_page->flags & (PG_type_mask | PG_domain_mask)) !=
-                  (PGT_writeable_page | current->domain)) || 
-                 (buf_page->tot_count != 1) )
-            {
-               DPRINTK("Need a mapped-once writeable page (%ld/%ld/%08lx)\n",
-               buf_page->type_count, buf_page->tot_count, buf_page->flags);
-                make_rx_response(vif, rx.id, 0, RING_STATUS_BAD_PAGE, 0);
-                goto rx_unmap_and_continue;
-            }
+        if ( ((buf_page->flags & (PG_type_mask | PG_domain_mask)) !=
+              (PGT_writeable_page | p->domain)) || 
+             (buf_page->tot_count != 1) )
+        {
+            DPRINTK("Need a mapped-once writeable page (%ld/%ld/%08lx)\n",
+                    buf_page->type_count, buf_page->tot_count, 
+                    buf_page->flags);
+            make_rx_response(vif, rx.id, 0, RING_STATUS_BAD_PAGE, 0);
+            goto rx_unmap_and_continue;
+        }
             
-            /*
-             * The pte they passed was good, so take it away from them. We 
-             * also lock down the page-table page, so it doesn't go away.
-             */
-            get_page_type(pte_page);
-            get_page_tot(pte_page);
-            *ptep &= ~_PAGE_PRESENT;
-            buf_page->flags = buf_page->type_count = buf_page->tot_count = 0;
-            list_del(&buf_page->list);
-
-            vif->rx_shadow_ring[j].id          = rx.id;
-            vif->rx_shadow_ring[j].pte_ptr     = rx.addr;
-            vif->rx_shadow_ring[j].buf_pfn     = buf_pfn;
-            vif->rx_shadow_ring[j].flush_count = (unsigned short) 
-                atomic_read(&tlb_flush_count[smp_processor_id()]);
-            j = RX_RING_INC(j);
+        /*
+         * The pte they passed was good, so take it away from them. We also
+         * lock down the page-table page, so it doesn't go away.
+         */
+        get_page_type(pte_page);
+        get_page_tot(pte_page);
+        *ptep &= ~_PAGE_PRESENT;
+        buf_page->flags = buf_page->type_count = buf_page->tot_count = 0;
+        list_del(&buf_page->list);
+
+        vif->rx_shadow_ring[j].id          = rx.id;
+        vif->rx_shadow_ring[j].pte_ptr     = rx.addr;
+        vif->rx_shadow_ring[j].buf_pfn     = buf_pfn;
+        vif->rx_shadow_ring[j].flush_count = (unsigned short) 
+            atomic_read(&tlb_flush_count[smp_processor_id()]);
+        j = RX_RING_INC(j);
             
-        rx_unmap_and_continue:
-            unmap_domain_mem(ptep);
-            spin_unlock_irq(&current->page_lock);
-        }
+    rx_unmap_and_continue:
+        unmap_domain_mem(ptep);
+        spin_unlock_irq(&p->page_lock);
+    }
+
+    vif->rx_req_cons = i;
+
+    if ( vif->rx_prod != j )
+    {
+        smp_mb(); /* Let other CPUs see new descriptors first. */
+        vif->rx_prod = j;
+    }
+
+    return 0;
+}
+
+
+long flush_bufs_for_vif(net_vif_t *vif)
+{
+    int i;
+    unsigned long *pte, flags;
+    struct pfn_info *page;
+    struct task_struct *p = vif->domain;
+    rx_shadow_entry_t *rx;
+    net_ring_t *shared_rings = vif->shared_rings;
+    net_idx_t *shared_idxs = vif->shared_idxs;
+
+    /* Return any outstanding receive buffers to the guest OS. */
+    spin_lock_irqsave(&p->page_lock, flags);
+    for ( i = vif->rx_req_cons; 
+          (i != shared_idxs->rx_req_prod) && 
+              (((vif->rx_resp_prod-i) & (RX_RING_SIZE-1)) != 1); 
+          i = RX_RING_INC(i) )
+    {
+        make_rx_response(vif, shared_rings->rx_ring[i].req.id, 0,
+                         RING_STATUS_DROPPED, 0);
+    }
+    vif->rx_req_cons = i;
+    for ( i = vif->rx_cons; i != vif->rx_prod; i = RX_RING_INC(i) )
+    {
+        rx = &vif->rx_shadow_ring[i];
+
+        /* Release the page-table page. */
+        page = frame_table + (rx->pte_ptr >> PAGE_SHIFT);
+        put_page_type(page);
+        put_page_tot(page);
 
-        vif->rx_req_cons = i;
+        /* Give the buffer page back to the domain. */
+        page = frame_table + rx->buf_pfn;
+        list_add(&page->list, &p->pg_head);
+        page->flags = vif->domain->domain;
 
-        if ( vif->rx_prod != j )
+        /* Patch up the PTE if it hasn't changed under our feet. */
+        pte = map_domain_mem(rx->pte_ptr);
+        if ( !(*pte & _PAGE_PRESENT) )
         {
-            smp_mb(); /* Let other CPUs see new descriptors first. */
-            vif->rx_prod = j;
+            *pte = (rx->buf_pfn<<PAGE_SHIFT) | (*pte & ~PAGE_MASK) | 
+                _PAGE_RW | _PAGE_PRESENT;
+            page->flags |= PGT_writeable_page | PG_need_flush;
+            page->type_count = page->tot_count = 1;
         }
+        unmap_domain_mem(pte);
+
+        make_rx_response(vif, rx->id, 0, RING_STATUS_DROPPED, 0);
     }
+    vif->rx_cons = i;
+    spin_unlock_irqrestore(&p->page_lock, flags);
+
+    /*
+     * Flush pending transmit buffers. The guest may still have to wait for
+     * buffers that are queued at a physical NIC.
+     */
+    spin_lock_irqsave(&vif->tx_lock, flags);
+    for ( i = vif->tx_req_cons; 
+          (i != shared_idxs->tx_req_prod) && 
+              (((vif->tx_resp_prod-i) & (TX_RING_SIZE-1)) != 1); 
+          i = TX_RING_INC(i) )
+    {
+        __make_tx_response(vif, shared_rings->tx_ring[i].req.id, 
+                           RING_STATUS_DROPPED);
+    }
+    vif->tx_req_cons = i;
+    spin_unlock_irqrestore(&vif->tx_lock, flags);
 
     return 0;
 }
 
 
+/*
+ * do_net_io_op:
+ * 
+ * Called from guest OS to notify updates to its transmit and/or receive
+ * descriptor rings.
+ */
+long do_net_io_op(unsigned int op, unsigned int idx)
+{
+    net_vif_t *vif;
+    long ret;
+
+    perfc_incr(net_hypercalls);
+
+    if ( (vif = current->net_vif_list[idx]) == NULL )
+        return -EINVAL;
+
+    switch ( op )
+    {
+    case NETOP_PUSH_BUFFERS:
+        ret = get_bufs_from_vif(vif);
+        break;
+
+    case NETOP_FLUSH_BUFFERS:
+        ret = flush_bufs_for_vif(vif);
+        break;
+
+    default:
+        ret = -EINVAL;
+        break;
+    }
+
+    return ret;
+}
+
+
 static void __make_tx_response(net_vif_t     *vif, 
                                unsigned short id, 
                                unsigned char  st)
index 2592b88ec39766dbc110e29231a22137e2def0f5..cc3c91d704535f076ca28d9e214609366c4fbfbb 100644 (file)
@@ -40,7 +40,7 @@ static inline void signal_requests_to_xen(void)
 {
     DISABLE_SCATTERGATHER();
     blk_ring->req_prod = req_prod;
-    HYPERVISOR_block_io_op();
+    HYPERVISOR_block_io_op(BLKOP_PUSH_BUFFERS);
 }
 
 
index 51d86c8fb3f726ed1213d98f8ee7965231d81035..be46c4c28f3ee9bd89a4268a75b80324b0f43ab3 100644 (file)
@@ -249,7 +249,7 @@ static void network_alloc_rx_buffers(struct net_device *dev)
     /* Batch Xen notifications. */
     if ( np->rx_bufs_to_notify > (RX_MAX_ENTRIES/4) )
     {
-        HYPERVISOR_net_update();
+        HYPERVISOR_net_io_op(NETOP_PUSH_BUFFERS, np->idx);
         np->rx_bufs_to_notify = 0;
     }
 }
@@ -322,7 +322,7 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev)
     /* Only notify Xen if there are no outstanding responses. */
     mb();
     if ( np->net_idx->tx_resp_prod == i )
-        HYPERVISOR_net_update();
+        HYPERVISOR_net_io_op(NETOP_PUSH_BUFFERS, np->idx);
 
     return 0;
 }
index a89fd8eda49a7f527dd2eaefcfe0c09c59ad5740..11a1324c748c7810de75d7cb9db4ab2a772c7b27 100644 (file)
@@ -9,9 +9,8 @@
 #include <asm/desc.h>
 
 /* Offsets in start_info structure */
-#define SHARED_INFO  4
-#define MOD_START   12
-#define MOD_LEN     16
+#define MOD_START   4
+#define MOD_LEN     8
                 
 startup_32:
         cld
@@ -35,19 +34,16 @@ startup_32:
                 
         /* Clear BSS first so that there are no surprises... */
 2:      xorl %eax,%eax
-       movl $SYMBOL_NAME(__bss_start),%edi
-       movl $SYMBOL_NAME(_end),%ecx
-       subl %edi,%ecx
-       rep stosb
+        movl $SYMBOL_NAME(__bss_start),%edi
+        movl $SYMBOL_NAME(_end),%ecx
+        subl %edi,%ecx
+        rep stosb
 
         /* Copy the necessary stuff from start_info structure. */
-        /* We need to copy shared_info early, so that sti/cli work */
-        mov  SHARED_INFO(%esi),%eax
-        mov  %eax,SYMBOL_NAME(HYPERVISOR_shared_info)
         mov  $SYMBOL_NAME(start_info_union),%edi
         mov  $128,%ecx
         rep movsl
-                
+                        
         jmp SYMBOL_NAME(start_kernel)
 
 ENTRY(stack_start)
index b2532d7b582c7e366a3fc5ff6df40f5c9ba24e3a..df9a6d45312ff8fc0259aa0e5c8b282727e8aba9 100644 (file)
 #include <asm/hypervisor.h>
 #include <asm/hypervisor-ifs/dom0_ops.h>
 
-shared_info_t *HYPERVISOR_shared_info;
+/*
+ * Point at the empty zero page to start with. We map the real shared_info
+ * page as soon as fixmap is up and running.
+ */
+shared_info_t *HYPERVISOR_shared_info = empty_zero_page;
 
 unsigned long *phys_to_machine_mapping;
 
index 7f9967531ea8233cff91092b0a945ac2910deb23..633472b9d0724fab4179f7f0941e7c9e4f968681 100644 (file)
@@ -43,50 +43,50 @@ static unsigned long totalhigh_pages;
 
 int do_check_pgt_cache(int low, int high)
 {
-       int freed = 0;
-       if(pgtable_cache_size > high) {
-               do {
+    int freed = 0;
+    if(pgtable_cache_size > high) {
+        do {
             if (!QUICKLIST_EMPTY(pgd_quicklist)) {
-                               free_pgd_slow(get_pgd_fast());
-                               freed++;
-                       }
+                free_pgd_slow(get_pgd_fast());
+                freed++;
+            }
             if (!QUICKLIST_EMPTY(pte_quicklist)) {
-                               pte_free_slow(pte_alloc_one_fast(NULL, 0));
-                               freed++;
-                       }
-               } while(pgtable_cache_size > low);
-       }
-       return freed;
+                pte_free_slow(pte_alloc_one_fast(NULL, 0));
+                freed++;
+            }
+        } while(pgtable_cache_size > low);
+    }
+    return freed;
 }
 
 void show_mem(void)
 {
-       int i, total = 0, reserved = 0;
-       int shared = 0, cached = 0;
-       int highmem = 0;
-
-       printk("Mem-info:\n");
-       show_free_areas();
-       printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
-       i = max_mapnr;
-       while (i-- > 0) {
-               total++;
-               if (PageHighMem(mem_map+i))
-                       highmem++;
-               if (PageReserved(mem_map+i))
-                       reserved++;
-               else if (PageSwapCache(mem_map+i))
-                       cached++;
-               else if (page_count(mem_map+i))
-                       shared += page_count(mem_map+i) - 1;
-       }
-       printk("%d pages of RAM\n", total);
-       printk("%d pages of HIGHMEM\n",highmem);
-       printk("%d reserved pages\n",reserved);
-       printk("%d pages shared\n",shared);
-       printk("%d pages swap cached\n",cached);
-       printk("%ld pages in page table cache\n",pgtable_cache_size);
-       show_buffers();
+    int i, total = 0, reserved = 0;
+    int shared = 0, cached = 0;
+    int highmem = 0;
+
+    printk("Mem-info:\n");
+    show_free_areas();
+    printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
+    i = max_mapnr;
+    while (i-- > 0) {
+        total++;
+        if (PageHighMem(mem_map+i))
+            highmem++;
+        if (PageReserved(mem_map+i))
+            reserved++;
+        else if (PageSwapCache(mem_map+i))
+            cached++;
+        else if (page_count(mem_map+i))
+            shared += page_count(mem_map+i) - 1;
+    }
+    printk("%d pages of RAM\n", total);
+    printk("%d pages of HIGHMEM\n",highmem);
+    printk("%d reserved pages\n",reserved);
+    printk("%d pages shared\n",shared);
+    printk("%d pages swap cached\n",cached);
+    printk("%ld pages in page table cache\n",pgtable_cache_size);
+    show_buffers();
 }
 
 /* References to section boundaries */
@@ -95,118 +95,118 @@ extern char _text, _etext, _edata, __bss_start, _end;
 extern char __init_begin, __init_end;
 
 static inline void set_pte_phys (unsigned long vaddr,
-                       unsigned long phys, pgprot_t flags)
+                                 unsigned long phys, pgprot_t flags)
 {
-       pgprot_t prot;
-       pgd_t *pgd;
-       pmd_t *pmd;
-       pte_t *pte;
-
-       pgd = init_mm.pgd + __pgd_offset(vaddr);
-       if (pgd_none(*pgd)) {
-               printk("PAE BUG #00!\n");
-               return;
-       }
-       pmd = pmd_offset(pgd, vaddr);
-       if (pmd_none(*pmd)) {
-               printk("PAE BUG #01!\n");
-               return;
-       }
-       pte = pte_offset(pmd, vaddr);
-
-       if (pte_val(*pte))
-               pte_ERROR(*pte);
-
-       pgprot_val(prot) = pgprot_val(PAGE_KERNEL) | pgprot_val(flags);
-
-       /* We queue directly, avoiding hidden phys->machine translation. */
-       queue_l1_entry_update(pte, phys | pgprot_val(prot));
-
-       /*
-        * It's enough to flush this one mapping.
-        * (PGE mappings get flushed as well)
-        */
-       __flush_tlb_one(vaddr);
+    pgprot_t prot;
+    pgd_t *pgd;
+    pmd_t *pmd;
+    pte_t *pte;
+
+    pgd = init_mm.pgd + __pgd_offset(vaddr);
+    if (pgd_none(*pgd)) {
+        printk("PAE BUG #00!\n");
+        return;
+    }
+    pmd = pmd_offset(pgd, vaddr);
+    if (pmd_none(*pmd)) {
+        printk("PAE BUG #01!\n");
+        return;
+    }
+    pte = pte_offset(pmd, vaddr);
+
+    if (pte_val(*pte))
+        pte_ERROR(*pte);
+
+    pgprot_val(prot) = pgprot_val(PAGE_KERNEL) | pgprot_val(flags);
+
+    /* We queue directly, avoiding hidden phys->machine translation. */
+    queue_l1_entry_update(pte, phys | pgprot_val(prot));
+
+    /*
+     * It's enough to flush this one mapping.
+     * (PGE mappings get flushed as well)
+     */
+    __flush_tlb_one(vaddr);
 }
 
 void __set_fixmap (enum fixed_addresses idx, unsigned long phys, 
                    pgprot_t flags)
 {
-       unsigned long address = __fix_to_virt(idx);
+    unsigned long address = __fix_to_virt(idx);
 
-       if (idx >= __end_of_fixed_addresses) {
-               printk("Invalid __set_fixmap\n");
-               return;
-       }
-       set_pte_phys(address, phys, flags);
+    if (idx >= __end_of_fixed_addresses) {
+        printk("Invalid __set_fixmap\n");
+        return;
+    }
+    set_pte_phys(address, phys, flags);
 }
 
 static void __init fixrange_init (unsigned long start, 
                                   unsigned long end, pgd_t *pgd_base)
 {
-       pgd_t *pgd, *kpgd;
-       pmd_t *pmd, *kpmd;
-       pte_t *pte, *kpte;
-       int i, j;
-       unsigned long vaddr;
-
-       vaddr = start;
-       i = __pgd_offset(vaddr);
-       j = __pmd_offset(vaddr);
-       pgd = pgd_base + i;
-
-       for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
+    pgd_t *pgd, *kpgd;
+    pmd_t *pmd, *kpmd;
+    pte_t *pte, *kpte;
+    int i, j;
+    unsigned long vaddr;
+
+    vaddr = start;
+    i = __pgd_offset(vaddr);
+    j = __pmd_offset(vaddr);
+    pgd = pgd_base + i;
+
+    for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
 #if CONFIG_X86_PAE
-               if (pgd_none(*pgd)) {
-                       pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
-                       set_pgd(pgd, __pgd(__pa(pmd) + 0x1));
-                       if (pmd != pmd_offset(pgd, 0))
-                               printk("PAE BUG #02!\n");
-               }
-               pmd = pmd_offset(pgd, vaddr);
+        if (pgd_none(*pgd)) {
+            pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+            set_pgd(pgd, __pgd(__pa(pmd) + 0x1));
+            if (pmd != pmd_offset(pgd, 0))
+                printk("PAE BUG #02!\n");
+        }
+        pmd = pmd_offset(pgd, vaddr);
 #else
-               pmd = (pmd_t *)pgd;
+        pmd = (pmd_t *)pgd;
 #endif
-               for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
-                       if (pmd_none(*pmd)) {
-                               pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
-                               clear_page(pte);
-                               kpgd = pgd_offset_k((unsigned long)pte);
-                               kpmd = pmd_offset(kpgd, (unsigned long)pte);
-                               kpte = pte_offset(kpmd, (unsigned long)pte);
-                               queue_l1_entry_update(kpte,
+        for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
+            if (pmd_none(*pmd)) {
+                pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+                clear_page(pte);
+                kpgd = pgd_offset_k((unsigned long)pte);
+                kpmd = pmd_offset(kpgd, (unsigned long)pte);
+                kpte = pte_offset(kpmd, (unsigned long)pte);
+                queue_l1_entry_update(kpte,
                                       (*(unsigned long *)kpte)&~_PAGE_RW);
 
-                               set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
-                       }
-                       vaddr += PMD_SIZE;
-               }
-               j = 0;
-       }
+                set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
+            }
+            vaddr += PMD_SIZE;
+        }
+        j = 0;
+    }
        
-       XENO_flush_page_update_queue();
+    XENO_flush_page_update_queue();
 }
 
 
 static void __init zone_sizes_init(void)
 {
-       unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
-       unsigned int max_dma, high, low;
-
-       max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
-       low = max_low_pfn;
-       high = highend_pfn;
-
-       if (low < max_dma)
-               zones_size[ZONE_DMA] = low;
-       else {
-               zones_size[ZONE_DMA] = max_dma;
-               zones_size[ZONE_NORMAL] = low - max_dma;
+    unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+    unsigned int max_dma, high, low;
+
+    max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+    low = max_low_pfn;
+    high = highend_pfn;
+
+    if (low < max_dma)
+        zones_size[ZONE_DMA] = low;
+    else {
+        zones_size[ZONE_DMA] = max_dma;
+        zones_size[ZONE_NORMAL] = low - max_dma;
 #ifdef CONFIG_HIGHMEM
-               zones_size[ZONE_HIGHMEM] = high - low;
+        zones_size[ZONE_HIGHMEM] = high - low;
 #endif
-       }
-       free_area_init(zones_size);
+    }
+    free_area_init(zones_size);
 }
 
 /*
@@ -218,60 +218,65 @@ static void __init zone_sizes_init(void)
  */
 void __init paging_init(void)
 {
-       unsigned long vaddr;
+    unsigned long vaddr;
 
-       zone_sizes_init();
+    zone_sizes_init();
 
-       /*
-        * Fixed mappings, only the page table structure has to be created -
-        * mappings will be set by set_fixmap():
-        */
-       vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
-       fixrange_init(vaddr, HYPERVISOR_VIRT_START, init_mm.pgd);
+    /*
+     * Fixed mappings, only the page table structure has to be created -
+     * mappings will be set by set_fixmap():
+     */
+    vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
+    fixrange_init(vaddr, HYPERVISOR_VIRT_START, init_mm.pgd);
+
+    /* Cheesy: this can probably be moved to the blkdev driver. */
+    set_fixmap(FIX_BLKRING_BASE, start_info.blk_ring);
 
-       /* Cheesy: this can probably be moved to the blkdev driver. */
-       set_fixmap(FIX_BLKRING_BASE, start_info.blk_ring);
+    /* Switch to the real shared_info page, and clear the dummy page. */
+    set_fixmap(FIX_SHARED_INFO, start_info.shared_info);
+    HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
+    memset(empty_zero_page, 0, sizeof(empty_zero_page));
 
 #ifdef CONFIG_HIGHMEM
 #error
-       kmap_init();
+    kmap_init();
 #endif
 }
 
 static inline int page_is_ram (unsigned long pagenr)
 {
-       return 1;
+    return 1;
 }
 
 #ifdef CONFIG_HIGHMEM
 void __init one_highpage_init(struct page *page, int pfn, int bad_ppro)
 {
-       if (!page_is_ram(pfn)) {
-               SetPageReserved(page);
-               return;
-       }
+    if (!page_is_ram(pfn)) {
+        SetPageReserved(page);
+        return;
+    }
        
-       if (bad_ppro && page_kills_ppro(pfn)) {
-               SetPageReserved(page);
-               return;
-       }
+    if (bad_ppro && page_kills_ppro(pfn)) {
+        SetPageReserved(page);
+        return;
+    }
        
-       ClearPageReserved(page);
-       set_bit(PG_highmem, &page->flags);
-       atomic_set(&page->count, 1);
-       __free_page(page);
-       totalhigh_pages++;
+    ClearPageReserved(page);
+    set_bit(PG_highmem, &page->flags);
+    atomic_set(&page->count, 1);
+    __free_page(page);
+    totalhigh_pages++;
 }
 #endif /* CONFIG_HIGHMEM */
 
 static void __init set_max_mapnr_init(void)
 {
 #ifdef CONFIG_HIGHMEM
-        highmem_start_page = mem_map + highstart_pfn;
-        max_mapnr = num_physpages = highend_pfn;
-        num_mappedpages = max_low_pfn;
+    highmem_start_page = mem_map + highstart_pfn;
+    max_mapnr = num_physpages = highend_pfn;
+    num_mappedpages = max_low_pfn;
 #else
-        max_mapnr = num_mappedpages = num_physpages = max_low_pfn;
+    max_mapnr = num_mappedpages = num_physpages = max_low_pfn;
 #endif
 }
 
@@ -279,112 +284,112 @@ static int __init free_pages_init(void)
 {
 #ifdef CONFIG_HIGHMEM
 #error Where is this supposed to be initialised?
-        int bad_ppro;
+    int bad_ppro;
 #endif
-       int reservedpages, pfn;
-
-       /* this will put all low memory onto the freelists */
-       totalram_pages += free_all_bootmem();
-
-       reservedpages = 0;
-       for (pfn = 0; pfn < max_low_pfn; pfn++) {
-               /*
-                * Only count reserved RAM pages
-                */
-               if (page_is_ram(pfn) && PageReserved(mem_map+pfn))
-                       reservedpages++;
-       }
+    int reservedpages, pfn;
+
+    /* this will put all low memory onto the freelists */
+    totalram_pages += free_all_bootmem();
+
+    reservedpages = 0;
+    for (pfn = 0; pfn < max_low_pfn; pfn++) {
+        /*
+         * Only count reserved RAM pages
+         */
+        if (page_is_ram(pfn) && PageReserved(mem_map+pfn))
+            reservedpages++;
+    }
 #ifdef CONFIG_HIGHMEM
-       for (pfn = highend_pfn-1; pfn >= highstart_pfn; pfn--)
-               one_highpage_init((struct page *) (mem_map + pfn), pfn, bad_ppro);
-       totalram_pages += totalhigh_pages;
+    for (pfn = highend_pfn-1; pfn >= highstart_pfn; pfn--)
+        one_highpage_init((struct page *) (mem_map + pfn), pfn, bad_ppro);
+    totalram_pages += totalhigh_pages;
 #endif
-       return reservedpages;
+    return reservedpages;
 }
 
 void __init mem_init(void)
 {
-       int codesize, reservedpages, datasize, initsize;
+    int codesize, reservedpages, datasize, initsize;
 
-       if (!mem_map)
-               BUG();
+    if (!mem_map)
+        BUG();
        
-       set_max_mapnr_init();
+    set_max_mapnr_init();
 
-       high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
+    high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
 
-       /* clear the zero-page */
-       memset(empty_zero_page, 0, PAGE_SIZE);
+    /* clear the zero-page */
+    memset(empty_zero_page, 0, PAGE_SIZE);
 
-       reservedpages = free_pages_init();
+    reservedpages = free_pages_init();
 
-       codesize =  (unsigned long) &_etext - (unsigned long) &_text;
-       datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
-       initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
+    codesize =  (unsigned long) &_etext - (unsigned long) &_text;
+    datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
+    initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
 
-       printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
-               (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
-               max_mapnr << (PAGE_SHIFT-10),
-               codesize >> 10,
-               reservedpages << (PAGE_SHIFT-10),
-               datasize >> 10,
-               initsize >> 10,
-               (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
-              );
+    printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
+           (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+           max_mapnr << (PAGE_SHIFT-10),
+           codesize >> 10,
+           reservedpages << (PAGE_SHIFT-10),
+           datasize >> 10,
+           initsize >> 10,
+           (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
+        );
 
     boot_cpu_data.wp_works_ok = 1;
 }
 
 void free_initmem(void)
 {
-       unsigned long addr;
-
-       addr = (unsigned long)(&__init_begin);
-       for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
-               ClearPageReserved(virt_to_page(addr));
-               set_page_count(virt_to_page(addr), 1);
-               free_page(addr);
-               totalram_pages++;
-       }
-       printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
+    unsigned long addr;
+
+    addr = (unsigned long)(&__init_begin);
+    for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
+        ClearPageReserved(virt_to_page(addr));
+        set_page_count(virt_to_page(addr), 1);
+        free_page(addr);
+        totalram_pages++;
+    }
+    printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-       if (start < end)
-               printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
-       for (; start < end; start += PAGE_SIZE) {
-               ClearPageReserved(virt_to_page(start));
-               set_page_count(virt_to_page(start), 1);
-               free_page(start);
-               totalram_pages++;
-       }
+    if (start < end)
+        printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+    for (; start < end; start += PAGE_SIZE) {
+        ClearPageReserved(virt_to_page(start));
+        set_page_count(virt_to_page(start), 1);
+        free_page(start);
+        totalram_pages++;
+    }
 }
 #endif
 
 void si_meminfo(struct sysinfo *val)
 {
-       val->totalram = totalram_pages;
-       val->sharedram = 0;
-       val->freeram = nr_free_pages();
-       val->bufferram = atomic_read(&buffermem_pages);
-       val->totalhigh = totalhigh_pages;
-       val->freehigh = nr_free_highpages();
-       val->mem_unit = PAGE_SIZE;
-       return;
+    val->totalram = totalram_pages;
+    val->sharedram = 0;
+    val->freeram = nr_free_pages();
+    val->bufferram = atomic_read(&buffermem_pages);
+    val->totalhigh = totalhigh_pages;
+    val->freehigh = nr_free_highpages();
+    val->mem_unit = PAGE_SIZE;
+    return;
 }
 
 #if defined(CONFIG_X86_PAE)
 struct kmem_cache_s *pae_pgd_cachep;
 void __init pgtable_cache_init(void)
 {
-       /*
-        * PAE pgds must be 16-byte aligned:
+    /*
+     * PAE pgds must be 16-byte aligned:
         */
-       pae_pgd_cachep = kmem_cache_create("pae_pgd", 32, 0,
-               SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, NULL, NULL);
-       if (!pae_pgd_cachep)
-               panic("init_pae(): Cannot alloc pae_pgd SLAB cache");
+    pae_pgd_cachep = kmem_cache_create("pae_pgd", 32, 0,
+                                       SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, NULL, NULL);
+    if (!pae_pgd_cachep)
+        panic("init_pae(): Cannot alloc pae_pgd SLAB cache");
 }
 #endif /* CONFIG_X86_PAE */
index 590ecf996194481f3c9750586398fb1fe83c7104..ec7083a359ac159ee5bb9e3a7a4ccf0aba56637c 100644 (file)
@@ -47,15 +47,16 @@ enum fixed_addresses {
        FIX_NETRING1_BASE,
        FIX_NETRING2_BASE,
        FIX_NETRING3_BASE,
+        FIX_SHARED_INFO,
 
 #ifdef CONFIG_VGA_CONSOLE
 #define NR_FIX_BTMAPS   32  /* 128KB For the Dom0 VGA Console A0000-C0000 */
 #else
-#define NR_FIX_BTMAPS   1   /* have on page incase anyone wants it in future */
+#define NR_FIX_BTMAPS   1   /* in case anyone wants it in future... */
 #endif
         FIX_BTMAP_END,
         FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1,
-       /* our bt_ioremap is permenant unlike other architectures */
+       /* our bt_ioremap is permanent, unlike other architectures */
        
        __end_of_permanent_fixed_addresses,
        __end_of_fixed_addresses = __end_of_permanent_fixed_addresses
index 80b2c28da0552b8473a5780d171ce69baa3f393a..57a0e30d7918d7a4bf97f43b4eea53c750213d74 100644 (file)
@@ -219,12 +219,13 @@ static inline int HYPERVISOR_set_callbacks(
     return ret;
 }
 
-static inline int HYPERVISOR_net_update(void)
+static inline int HYPERVISOR_net_io_op(unsigned int op, unsigned int idx)
 {
     int ret;
     __asm__ __volatile__ (
         TRAP_INSTR
-        : "=a" (ret) : "0" (__HYPERVISOR_net_update) );
+        : "=a" (ret) : "0" (__HYPERVISOR_net_io_op),
+        "b" (op), "c" (idx) );
 
     return ret;
 }
@@ -281,12 +282,13 @@ static inline int HYPERVISOR_network_op(void *network_op)
     return ret;
 }
 
-static inline int HYPERVISOR_block_io_op(void)
+static inline int HYPERVISOR_block_io_op(unsigned int op)
 {
     int ret;
     __asm__ __volatile__ (
         TRAP_INSTR
-        : "=a" (ret) : "0" (__HYPERVISOR_block_io_op) ); 
+        : "=a" (ret) : "0" (__HYPERVISOR_block_io_op),
+        "b" (op) ); 
 
     return ret;
 }